use warp::reply::{Json, WithStatus};

use crate::core::cluster::CLUSTERS;
use crate::core::file_content::FileContent;
use crate::core::git::{get_cluster_diff_list, get_latest_version, get_version_file_content};
use crate::router::basic::{self};
use crate::{make_resp, require_token};

pub fn clusters(authorization: String) -> WithStatus<Json> {
	require_token!(authorization);

	let mut clusters_name = Vec::new();
	let clusters = CLUSTERS.lock().unwrap();
	for key in clusters.keys() {
		clusters_name.push(key);
	}

	make_resp!(0, "".to_string(), clusters_name);
}

pub fn cluster_diff(cluster_name: String, version: String, authorization: String) -> WithStatus<Json> {
	require_token!(authorization);

	let cluster_name = match CLUSTERS.lock().unwrap().get(&cluster_name) {
		Some(cluster) => cluster.name.clone(),
		None => "default".to_string(),
	};

	match get_cluster_diff_list(&cluster_name, &version) {
		Ok(list) => make_resp!(0, "ok".to_string(), list),
		Err(e) => make_resp!(1, e, ()),
	}
}

pub fn cluster_update(cluster_name: String, old_version: String, authorization: String) -> WithStatus<Json> {
	require_token!(authorization);

	let cluster_name = match CLUSTERS.lock().unwrap().get(&cluster_name) {
		Some(cluster) => cluster.name.clone(),
		None => "default".to_string(),
	};

	let diff_file_list = get_cluster_diff_list(&cluster_name, &old_version);
	if diff_file_list.is_err() {
		make_resp!(1, diff_file_list.unwrap_err(), ());
	}
	let diff_file_list = diff_file_list.unwrap();

	let latest_version = get_latest_version();
	let resp = get_version_file_content(&latest_version, &diff_file_list);
	if resp.is_err() {
		make_resp!(1, resp.unwrap_err(), ());
	}
	let resp = resp.unwrap();

	let resp = {
		#[derive(serde::Serialize)]
		struct ClusterUpdateResp {
			latest_version: String,
			update_content: Vec<FileContent>,
		}
		ClusterUpdateResp{
			latest_version,
			update_content: resp,
		}
	};
	
	make_resp!(0, "ok".to_string(), resp);
}

pub fn cluster_latest(cluster_name: String, authorization: String) -> WithStatus<Json> {
	require_token!(authorization);

	let cluster_name = match CLUSTERS.lock().unwrap().get(&cluster_name) {
		Some(cluster) => cluster.name.clone(),
		None => "default".to_string(),
	};

	let clusters = CLUSTERS.lock().unwrap();
	let cluster = clusters.get(&cluster_name).unwrap();
	let latest_version = get_latest_version();
	let mut file_list = cluster.files.clone();
	file_list.iter_mut().for_each(|path| {
		path.insert_str(0, &cluster_name.as_str());
	});

	let resp = get_version_file_content(&latest_version, &file_list);
	if resp.is_err() { make_resp!(1, resp.unwrap_err(), ()); }
	let resp = resp.unwrap();
	let resp = {
		#[derive(serde::Serialize)]
		struct ClusterLatestResp {
			latest_version: String,
			file_content: Vec<FileContent>,
		}
		ClusterLatestResp {
			latest_version,
			file_content: resp,
		}
	};
	make_resp!(0, "ok".to_string(), resp);
}
